package net.pimpas.web.tomcat.serviceprovider;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Embedded;

import net.pimpas.core.configuration.exception.ConfigurationException;
import net.pimpas.core.scanner.exception.ScannerException;
import net.pimpas.core.serviceprovider.ServiceProviderAnnotation;
import net.pimpas.core.serviceprovider.instancetype.ServiceProviderInstanceType;
import net.pimpas.logging.serviceprovider.LoggingServiceProvider;
import net.pimpas.logging.serviceprovider.LoggingServiceProviderFactoryImpl;
import net.pimpas.web.serviceprovider.WebServiceProvider;
import net.pimpas.web.serviceprovider.exception.WebServiceProviderException;
import net.pimpas.web.tomcat.serviceprovider.configuration.TomcatServiceProviderConfiguration;
import net.pimpas.web.tomcat.serviceprovider.scanner.TomcatServiceProviderScanner;

@ServiceProviderAnnotation(
		instanceType=ServiceProviderInstanceType.SINGLETON,
		serviceProviderType=WebServiceProvider.class)
public class TomcatServiceProviderImpl implements TomcatServiceProvider {
	
	private Embedded embedd;
	private LoggingServiceProvider logger = LoggingServiceProviderFactoryImpl.getLoggingServiceProvider(TomcatServiceProviderImpl.class);

	public void shutdown() throws WebServiceProviderException {
		logger.debug("[TomcatServer EMBEDD]: Shutingdown Server ...");
		try {
			this.getEmbedd().stop();
		} catch (LifecycleException e) {
			throw new WebServiceProviderException(e);
		}
	}

	public void startup() throws WebServiceProviderException {
		// run scanner
		TomcatServiceProviderScanner scanner = new TomcatServiceProviderScanner();
		
		try {
			scanner.scan();
		} catch (ScannerException e) {
			throw new WebServiceProviderException(e);
		}
		
		final TomcatServiceProviderConfiguration config = new TomcatServiceProviderConfiguration();
		config.setFilesConfiguration(scanner.getResult());
		this.setEmbedd(new Embedded());
		config.setEmbedd(this.getEmbedd());
		// consume
		new Thread() {
		
			@Override
			public void run() {
				try {
					config.consume();
				} catch (ConfigurationException e) {
					e.printStackTrace();
				}
			}
		}.start();
		
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				try {
					shutdown();
				} catch (WebServiceProviderException e) {
					e.printStackTrace();
				}
			}
		});
	}

	public void config() throws ConfigurationException {
		
	}
	
	public boolean isTerminated() {
		return false;
	}

	public Embedded getEmbedd() {
		return embedd;
	}

	public void setEmbedd(Embedded embedd) {
		this.embedd = embedd;
	}
}